const fs = require("fs");
const path = require("path");
const { loadConfig } = require("./utils/config");
const { prepareTempDirectory } = require("./utils/common");
const { checkFFmpeg, getAudioDuration } = require("./utils/ffmpeg");
const { parseASSWithDurations } = require("./utils/assParser");
const { filterValidImages, addTextToFirstFrame } = require("./utils/imageProcessor");
const { cleanupTempFiles, createImageSequence, createVideoWithSubtitles, createStaticImageVideo, mergeTwoAudio, mergeAudioVideo, mergeAssVideo } = require("./utils/videoProcessor");
const { addWaveformToVideo } = require("./utils/waveformGenerator");
const { mergeAssFilesWithWordPriority } = require("./utils/assMerger");

// 读取配置文件
const config = loadConfig();

/**
 * 处理首帧图片和标题
 * @param {string} outputDir - 输出目录路径
 * @returns {Promise<string|null>} 处理后的首帧图片路径或null
 */
async function processFirstFrame(outputDir) {
  // 检查首帧图片文件是否存在（只支持jpg格式）
  const inputDir = path.join(__dirname, "../input");
  let firstFramePath = path.resolve(inputDir, "first-frame.jpg");
  if (config.projectSettings.videoWidth < config.projectSettings.videoHeight) {
    firstFramePath = path.resolve(inputDir, "first-frame-long.jpg");
  }
  let firstFrameWithTextPath = null;

  if (fs.existsSync(inputDir) && fs.existsSync(firstFramePath)) {
    console.log("  首帧图片存在，开始处理...");
    // 在首帧图片上添加标题文字
    console.log("  正在处理标题...");
    // 检查是否有临时标题文件
    const titleFilePath = path.join(__dirname, "../temp/temp_title.txt");
    console.log("  检查临时标题文件...");
    let title = config.title || "Video Title";
    if (fs.existsSync(titleFilePath)) {
      console.log("  临时标题文件存在，读取标题...");
      title = fs.readFileSync(titleFilePath, "utf-8");
      console.log(`  使用临时标题: ${title}`);
    }
    else {
      console.log("  未找到临时标题文件，使用默认标题...");
    }

    firstFrameWithTextPath = await addTextToFirstFrame(firstFramePath, outputDir, title);
    console.log(`  添加标题到首帧: ${firstFrameWithTextPath}`);
  } else {
    // 如果首帧图片不存在，确保firstFrameWithTextPath为null
    console.log("凸(艹皿艹 )首帧图片不存在，跳过处理");
    firstFrameWithTextPath = null;
    process.exit(1);
  }

  return firstFrameWithTextPath;
}

/**
 * 使用FFmpeg创建视频
 * @param {string} audioFile - 音频文件路径
 * @param {string} subtitleFile - 字幕文件路径 (ASS格式)
 * @param {Array} mediaFiles - 媒体文件路径数组（包括图片和视频）
 * @param {string} outputFile - 输出视频文件路径
 * @param {number} datDuration - DAT文件总时长（秒），可选参数
 */
async function createVideoWithFFmpeg(audioFile, subtitleFile, mediaFiles, outputFile, datDuration = null) {
  if (!checkFFmpeg()) {
    console.error("！！！错误: 未找到FFmpeg。请确保FFmpeg路径正确。");
    process.exit(1);
  }

  // 解析字幕文件获取字幕时长信息
  let subtitles = parseASSWithDurations(subtitleFile);

  // 获取音频实际时长
  const audioDuration = getAudioDuration(audioFile);

  // 确定视频总时长：优先使用DAT时长，否则使用音频时长
  let videoDuration = audioDuration; // 默认使用音频时长
  if (datDuration && datDuration > 0) {
    videoDuration = datDuration;
  }

  // 过滤有效的媒体文件（包括图片和视频）
  const validMediaFiles = filterValidImages(mediaFiles);

  if (validMediaFiles.length === 0) {
    console.error("！！！错误: 没有找到有效的媒体文件（支持混合使用图片和视频）");
    process.exit(1);
  }

  // 创建临时目录来存储中间文件
  const tempDir = path.join(__dirname, "../temp_ffmpeg");
  prepareTempDirectory(tempDir);

  try {
    // 生成无音频的视频文件
    const tempVideoPath = path.join(tempDir, "temp_video.mp4");
    const tempVideoWithoutAss = path.join(tempDir, "temp_video_withoutAss.mp4");

    // 处理首帧图片
    const outputDir = path.join(__dirname, "../output");
    const firstFrameWithTextPath = await processFirstFrame(outputDir);

    let success = false;
    if (validMediaFiles.length > 0 && subtitles.length > 0) {
      // 使用支持混合媒体的序列创建方法
      const concatFilePath = createImageSequence(subtitles, validMediaFiles, tempDir, firstFrameWithTextPath, videoDuration);
      success = createVideoWithSubtitles(concatFilePath, subtitleFile, tempVideoPath);
    } else {
      let firstMedia = validMediaFiles[0];
      if (firstFrameWithTextPath && fs.existsSync(firstFrameWithTextPath)) {
        firstMedia = firstFrameWithTextPath;
      }

      success = createStaticImageVideo(firstMedia, subtitleFile, tempVideoPath, videoDuration);
    }

    if (!success) {
      throw new Error("无法生成无音频视频文件");
    }

    if (!fs.existsSync(tempVideoPath)) {
      throw new Error("无法生成无音频视频文件");
    }

    // 将config.json中指定的inputStartVoice对应的wav文件与audioFile合并
    let finalAudioFile = audioFile;
    const startVoicePath = path.join(__dirname, "..", config.inputStartVoice);
    console.log("  合并开始语音文件到主音频中...");
    const mergedAudioPath = path.join(tempDir, `merged_audio_${Date.now()}.mp3`);

    // 获取主音频时长
    const audioDuration = getAudioDuration(audioFile);

    // 使用现有的工具函数合并音频
    const mergeTwoSuccess = mergeTwoAudio(startVoicePath, audioFile, mergedAudioPath, audioDuration);

    if (mergeTwoSuccess && fs.existsSync(mergedAudioPath)) {
      console.log("  合并开始语音文件到音频中成功");
      finalAudioFile = mergedAudioPath;
    } else {
      console.warn("  合并开始语音文件到音频中失败，使用原始音频文件");
    }

    const mergeSuccess = mergeAudioVideo(tempVideoPath, finalAudioFile, tempVideoWithoutAss, videoDuration);
    if (!mergeSuccess) {
      throw new Error("！！！无法合并音频和视频");
    }

    // 合并两个ASS字幕文件为一个
    console.log("  合并主字幕和单词字幕文件...");
    const wordsAss = subtitleFile.replace(".ass", "_words.ass");
    const mergedAss = path.join(tempDir, "merged_subtitle.ass");
    mergeAssFilesWithWordPriority(subtitleFile, wordsAss, mergedAss);

    // 将合并后的字幕文件合并到视频中
    console.log("  合并字幕文件到视频中...");
    const mergeSubtitleSuccess = mergeAssVideo(tempVideoWithoutAss, mergedAss, outputFile);
    if (!mergeSubtitleSuccess) {
      throw new Error("无法合并字幕和视频");
    }

    // Add waveform if enabled in config
    const waveformConfig = config.waveform || { enabled: false };
    if (waveformConfig.enabled) {
      console.log("\n Waveform feature enabled. Adding waveform to video...");

      // Create a temporary file path for the video with waveform
      const videoWithWaveformPath = outputFile.replace(".mp4", "_with_waveform.mp4");

      // Add waveform to the video
      if (addWaveformToVideo(outputFile, videoWithWaveformPath)) {
        // If successful, replace the original video with the one with waveform
        fs.renameSync(videoWithWaveformPath, outputFile);
      } else {
        console.warn("  Failed to add waveform to video. Keeping original video.");
        // Clean up in case of failure
        fs.existsSync(videoWithWaveformPath) && fs.unlinkSync(videoWithWaveformPath);
      }
    }

    console.log("\n   Create_video_with_ffmpeg.js: 视频创建成功！");
  } catch (error) {
    console.error("！！！创建视频失败:", error.message);
    throw error;
  } finally {
    cleanupTempFiles(tempDir);
  }
}

// 导出函数
module.exports = {
  createVideoWithFFmpeg,
  processFirstFrame
};
